package edu.uta.cfl.engine;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

import edu.uta.cfl.data.Combo;
import edu.uta.cfl.data.Component;
import edu.uta.cfl.data.Parameter;
import edu.uta.cfl.data.SUT;
import edu.uta.cfl.data.SUT.SUTState;
import edu.uta.cfl.util.Constants;
import edu.uta.cfl.util.Util;

public class SUTInfoWriter {

	PrintWriter out;

	private final int lineSize = 100;

	public SUTInfoWriter(String file) {
		try {// write the file
			FileWriter outputFileReader = new FileWriter(file);
			out = new PrintWriter(outputFileReader);
		} catch (IOException ex) {
			Util.showErr("IOException:");
			ex.printStackTrace();
		}
	}

	public SUTInfoWriter() {

	}

	public void printSUT(SUT sut, int len) {
		out.println("#SoC: Suspiciousness of Combo\n#SoE: Suspiciousness of Environment\n");
		out.println("Rank ,\tCombo ,\tSoC ,\tSoE ");
		out.println("\n" + len + "-way suspicious combos");
		for (Combo cmb : sut.getSuspiciousCombos(len)) {
			out.format("%d , ", cmb.getRank());
			out.print(ComboManager.ToString(cmb, sut.getParameters()));
			out.format(" , %f , %f \n", cmb.getRankValue(),
					cmb.getEnvRankValue());
		}

		// if ( sut.getStatus() != SUT.SUTState.continuing){
		if (sut.getSuspiciousCombos(len - 1).size() > 0) {
			int cnt = 0;
			for (int i = 1; i < len; cnt += sut.getSuspiciousCombos(i++).size())
				;
			if (cnt > 0) {
				out.println("\n\nDerived combos:");

				for (int i = 1; i < len; i++) {
					if (sut.getSuspiciousCombos(i).size() > 0) {

						out.println("\n" + i + "-way suspicious combos");
						out.println("\nRank , \tCombo ,\tMin SoC  ");
						for (Combo cmb : sut.getSuspiciousCombos(i)) {
							out.format("%d , ", cmb.getRank());
							out.print(ComboManager.ToString(cmb,
									sut.getParameters()));
							out.format(
									" , %f \n",
									ComboManager.minSpcSubCmb(cmb,
											sut.getSuspiciousCombos(i + 1)));
							// ComboManager.maxRankSubCmb(cmb,
							// sut.getSuspiciousCombos(i+1)));
							// ComboManager.maxSpcSubCmb(cmb,
							// sut.getSuspiciousCombos(i+1)),
							// ComboManager.avgSpcSubCmb(cmb,
							// sut.getSuspiciousCombos(i+1)));
						}
					}
				}
			}
		}

		out.close();

	}

	public void printTCList(ArrayList<int[]> tcList, ArrayList<Parameter> prms) {
		out.println("# Executing these new test cases recommended by algorithm.");
		out.println("Tests");

		String output = "Test #, ";
		for (Parameter prm : prms)
			output += prm.getName() + ", ";

		try {
			out.println(output.substring(0, output.lastIndexOf(",")));
			int stater = 0;
			int i;
			String test;
			for (int[] tc : tcList) {

				test = "" + stater++ + " , ";
				for (i = 0; i < tc.length - 1; i++)
					test += prms.get(i).getValues().get(tc[i]) + " , ";

				test += tc[tc.length - 1];
				out.println(test);
			}


		} catch (Exception e) {
			// TODO: handle exception
			Util.showMsg("ey baba");
		}

		out.close();

	}

	public void summarizeOutpou(SUT sut, int len) {
		// int i=sut.getStrength()-1;
		// for ( ;i>= 0 && sut.getSuspiciousComponents(i+1).size()==0;i--);

		Util.showMsg("\nSummary of the system :");
		Util.showMsg(sut.getParameters().size() + " parameters, "
				+ sut.getTs().getMatrix().size() + " test cases, and "
				+ "strength of initial test set is " + sut.getStrength()
				+ ".\n");

		// int maxCombo = ComboManager.findFixLenCombos(sut.getParameters(),
		// sut.getStrength()).size();
		if (sut.getStatus() != SUTState.InducingTest) {
			Util.showMsg("Identified suspicious combos:");
			// for ( int l=0; l<=i ; l++)
			if (sut.getSuspiciousCombos(len).size() > 0) {
				Util.showMsg(sut.getSuspiciousCombos(len).size()
						+ " suspicious " + len + "-way combos out of "
						+ sut.getValidCombos(len).size() + ".");
			}
		}

		int failIn = 0;
		ArrayList<String> fails = new ArrayList<String>();
		for (int l = 0; l < len; l++) {
			for (Combo cmb : sut.getSuspiciousCombos(l + 1))
				if (cmb.isFailInd()) {
					failIn++;
					fails.add(ComboManager.ToString(cmb, sut.getParameters()));
				}
		}

		if (failIn > 0) {
			Util.showMsg("\n" + failIn + " failure-inducing combos:");
			printElementsLimitLS(fails);
		}

		if (sut.getStatus() == SUTState.noImprovement) {
			ArrayList<String> out = new ArrayList<String>();
			int i = 0;
			while (i < Constants.susCmbNum
					&& i < sut.getSuspiciousCombos(sut.getStrength()).size()) {
				out.add(ComboManager.ToString(
						sut.getSuspiciousCombos(sut.getStrength()).get(i++),
						sut.getParameters()));
			}
			Util.showMsg("\n" + out.size() + " most suspicious "
					+ sut.getStrength() + "-way combos:");
			printElementsLimitLS(out);
		}
	}

	private void printElementsLimitLS(ArrayList<String> out) {
		String output = "";
		int i = 0;
		do {

			do {
				output += out.get(i++) + "; ";
			} while ((i < out.size() && (output + out.get(i) + "; ").length() < lineSize));

			Util.showMsg(output);
			output = "";
		} while (i < out.size());
	}

	public void printSuspiciousness(SUT sut, int len) {
		for (Component cmp : sut.getSuspiciousComponents(len)) {
			int i = sut.getParameters().indexOf(cmp.getParameter());
			out.print(cmp.getParameter().getName()
					+ "="
					+ sut.getParameters().get(i).getValues()
							.get(cmp.getValue()));
			out.format(" , %f , %f , %f , %f\n", cmp.getPart1(),
					cmp.getPart2(), cmp.getPart3(), cmp.getRankValue());
		}

		out.close();

	}

}
